package datastructures;

import java.util.ArrayList;

import game.GameFieldPanel;

/**
 * A class that extends word. A EdgeWord is a word on the edge of each window in
 * the game-world. Every EdgeWord is constructed with a twin word that is
 * located in another window
 * 
 * @author Fredrik
 * 
 */
public class EdgeWord extends Word {

	/**
	 * 
	 */
	private static final long serialVersionUID = 8931379681306685524L;

	/** West edge */
	public static final int WEST_EDGE = (GameFieldPanel.WIDTH - GameFieldPanel.MIDDLE_REC_WIDTH) / 2;

	/** North edge */
	public static final int NORTH_EDGE = (GameFieldPanel.HEIGHT - GameFieldPanel.MIDDLE_REC_HEIGHT) / 2;

	/** East edge */
	public static final int EAST_EDGE = WEST_EDGE + GameFieldPanel.MIDDLE_REC_WIDTH;

	/** South edge */
	public static final int SOUTH_EDGE = NORTH_EDGE
			+ GameFieldPanel.MIDDLE_REC_HEIGHT;

	private EdgeWord twinWord;

	private int edge;

	/**
	 * Constructor creating a EdgeWord using a regular Word and setting the edge
	 * 
	 * @param word
	 * @param edge
	 */
	public EdgeWord(Word word, int edge) {
		super(word.getWordText());
		this.edge = edge;
		this.twinWord = new EdgeWord(this);
		setCoordinates(word.getCordinates());
		setAssociates(word.getAssociates());
	}

	/**
	 * Constructor creating a EdgeWord using another EdgeWord as twin
	 * 
	 * @param twinWord
	 */
	public EdgeWord(EdgeWord twinWord) {
		super(twinWord.getWordText());
		this.twinWord = twinWord;

		if (twinWord.getEdge() == WEST_EDGE) {
			this.edge = EAST_EDGE;
		} else if (twinWord.getEdge() == NORTH_EDGE) {
			this.edge = SOUTH_EDGE;
		} else if (twinWord.getEdge() == EAST_EDGE) {
			this.edge = WEST_EDGE;
		} else if (twinWord.getEdge() == SOUTH_EDGE) {
			this.edge = NORTH_EDGE;
		}

		setCoordinates(twinWord.getCordinates());
		setAssociates(twinWord.getAssociates());

	}

	/**
	 * (non-Javadoc)
	 * 
	 * @see datastructures.Word#setCoordinates(datastructures.Coordinate)
	 */
	@Override
	public void setCoordinates(Coordinate c) {

		Coordinate twinCoordinate = new Coordinate(c.getX(), c.getY());

		if (this.edge == WEST_EDGE) {
			c.setX(WEST_EDGE);
			twinCoordinate.setX(EAST_EDGE);
			if (c.getY() < NORTH_EDGE) {
				c.setY(NORTH_EDGE);
				twinCoordinate.setY(NORTH_EDGE);
			} else if (c.getY() > SOUTH_EDGE) {
				c.setY(SOUTH_EDGE);
				twinCoordinate.setY(SOUTH_EDGE);
			}
		} else if (this.edge == NORTH_EDGE) {
			c.setY(NORTH_EDGE);
			twinCoordinate.setY(SOUTH_EDGE);
			if (c.getX() < WEST_EDGE) {
				c.setX(WEST_EDGE);
				twinCoordinate.setX(WEST_EDGE);
			} else if (c.getX() > EAST_EDGE) {
				c.setX(EAST_EDGE);
				twinCoordinate.setX(EAST_EDGE);
			}

		} else if (this.edge == EAST_EDGE) {
			c.setX(EAST_EDGE);
			twinCoordinate.setX(WEST_EDGE);
			if (c.getY() < NORTH_EDGE) {
				c.setY(NORTH_EDGE);
				twinCoordinate.setY(NORTH_EDGE);
			} else if (c.getY() > SOUTH_EDGE) {
				c.setY(SOUTH_EDGE);
				twinCoordinate.setY(SOUTH_EDGE);
			}
		} else if (this.edge == SOUTH_EDGE) {
			c.setY(SOUTH_EDGE);
			twinCoordinate.setY(NORTH_EDGE);
			if (c.getX() < WEST_EDGE) {
				c.setX(WEST_EDGE);
				twinCoordinate.setX(WEST_EDGE);
			} else if (c.getX() > EAST_EDGE) {
				c.setX(EAST_EDGE);
				twinCoordinate.setX(EAST_EDGE);
			}
		}
		super.setCoordinates(c);
		this.twinWord.setThisTwinCoordinate(twinCoordinate);
	}

	/**
	 * (non-Javadoc)
	 * 
	 * @see datastructures.Word#guess(java.lang.String)
	 */
	@Override
	public boolean guess(String g) {
		if (!super.isTaken()) {
			if (super.guess(g)) {
				this.twinWord.guess(g);
				return true;
			}
			return false;

		}
		return false;
	}

	/**
	 * (non-Javadoc)
	 * 
	 * @see datastructures.Word#setAssociates(java.util.ArrayList)
	 */
	@Override
	public void setAssociates(ArrayList<String> ass) {
		super.setAssociates(ass);
		if (this.twinWord != null) {
			this.twinWord.setThisTwinAssociates(ass);
		}
	}

	/**
	 * (non-Javadoc)
	 * 
	 * @see datastructures.Word#setIsMiddle(boolean)
	 */
	@Override
	public void setIsMiddle(boolean b) {
		super.setIsMiddle(false);
	}

	/**
	 * (non-Javadoc)
	 * 
	 * @see datastructures.Word#setWord(java.lang.String)
	 */
	@Override
	public void setWord(String text) {
		super.setWord(text);
		if (this.twinWord != null) {
			this.twinWord.setThisTwinWord(text);
		}
	}

	/**
	 * (non-Javadoc)
	 * 
	 * @see datastructures.Word#setIsTaken(boolean)
	 */
	@Override
	public void setIsTaken(boolean taken) {
		super.setIsTaken(taken);
		this.twinWord.setThisTwinWordTaken(taken);
	}

	/**
	 * (non-Javadoc)
	 * 
	 * @see datastructures.Word#isVisible()
	 */
	@Override
	public boolean isVisible() {
		if (super.isVisible()) {
			return true;
		}
		return this.twinWord.isThisTwinWordVisible();

	}

	private boolean isThisTwinWordVisible() {
		return super.isVisible();
	}

	private void setThisTwinWordTaken(boolean taken) {
		super.setIsTaken(taken);
	}

	private void setThisTwinWord(String text) {
		super.setWord(text);

	}

	private void setThisTwinAssociates(ArrayList<String> ass) {
		super.setAssociates(ass);

	}

	private void setThisTwinCoordinate(Coordinate c) {
		super.setCoordinates(c);
	}

	/**
	 * Returns the Twin word
	 * @return a EdgeWord
	 */
	public EdgeWord getTwinWord() {
		return this.twinWord;
	}

	/**
	 * Returns the edge that this word is connected to
	 * @return a edge
	 */
	public int getEdge() {
		return this.edge;
	}

	/**
	 * Sets the edge on this word
	 * @param edge
	 */
	public void setEdge(int edge) {
		this.edge = edge;
	}

}
